use std::sync::Arc;

use axum::{
    middleware::from_extractor_with_state,
    routing::{delete, get, post},
    Router,
};

use crate::{
    jwt::UserClaimsData,
    middleware::{ClientInfo, RequiredAuth},
    AppState,
};

pub mod url;
pub mod user;

pub fn init_router(state: Arc<AppState>) -> Router {
    let r = Router::new()
        .nest("/user", user_router(state.clone()))
        .nest("/url", url_router(state.clone()));

    Router::new()
        .nest("/", r)
        .layer(from_extractor_with_state::<
            RequiredAuth<UserClaimsData>,
            Arc<AppState>,
        >(state.clone()))
}

fn user_router(state: Arc<AppState>) -> Router {
    Router::new()
        .route("/", get(user::index))
        .route("/change-pwd", post(user::change_password))
        .with_state(state)
}

pub fn visit_router(state: Arc<AppState>) -> Router {
    Router::new()
        .route("/:url", get(url::visit))
        .route("/:id/check-pwd", post(url::visit_check_pwd))
        .layer(from_extractor_with_state::<ClientInfo, Arc<AppState>>(
            state.clone(),
        ))
        .with_state(state)
}

pub fn url_router(state: Arc<AppState>) -> Router {
    Router::new()
        .route("/", post(url::add).get(url::list))
        .route("/:id", delete(url::del))
        .with_state(state)
}
